package eightDataType;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Ajie
 * @date 10/16/24
 * @function
 */
public class ByteArrayCutter {
    public static void main(String[] args) {
        // 定义 head 数组
        byte[] head = {0x02, 0x00, 0x00, 0x01, 0x00, 0x33, 0x31};

        byte[] a = {(byte)0xff};
        String s1 = new String(a);
        System.out.println("ByteArrayCutter:main:"+s1.length());

//        byte[] data = {
//                0x02, 0x00, 0x00, 0x01, 0x00, 0x33, 0x31,
//                0x02, 0x00, 0x00, 0x01, 0x00, 0x33, 0x31,
//                0x02, 0x00, 0x00, 0x01, 0x00, 0x33, 0x31
//        };
        // 示例 data 数组，头部和尾部都有多个连续的 head
//        byte[] data = {
////                (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // 脏数据
//                (byte) 0xff, // 脏数据
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0xff,//混乱的数据
//                (byte) 0x45, (byte) 0x67, (byte) 0x89,//混乱的数据
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x66,//真实的数据
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x67,//真实的数据
//        };

//        byte[] data = {
//                (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // 脏数据
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31
//        };
//        byte[] data = {
//                (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // 脏数据
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31,
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31
//        };

//        byte[] data = {
//                (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78//真实数据
//        };

        // 示例 data 数组，多个 head 和多个数据段
//        byte[] data = {
//                (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x67, (byte) 0x89, // 数据段
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31, // head
//                (byte) 0x45, (byte) 0x67, (byte) 0x89, // 数据段
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31, // head
//                (byte) 0x12, (byte) 0x34, (byte) 0x56, // 数据段
//                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31, // head
//                (byte) 0x9A, (byte) 0xBC, (byte) 0xDE, (byte) 0xF0}; // 数据段
        byte[] data = {
                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31, // head
                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x30,
                (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x33, (byte) 0x31}; // 数据段


        // 调用函数获取切割后的数组
        byte[] remainingData = cutDirtyDataBeforeHead(data, head);

        System.out.println("ByteArrayCutter:main:");
        // 调用函数获取切割后的数组
        remainingData = cutAllHeadsAndTails(remainingData, head);

        // 打印结果
        if (remainingData != null) {
            System.out.println("最终切割后的数据: ");
            for (byte b : remainingData) {
                System.out.printf("0x%02X ", b);
            }
        } else {
            System.out.println("数据为空或全部匹配 head");
        }



        // 调用函数获取最长的数据段
        byte[] longestSegment = getLongestDataSegment(data, head);
        longestSegment = removeCarriageReturns(longestSegment);
        System.out.println();
        // 打印最长的数据段
        if (longestSegment != null) {
            System.out.println("最长的数据段: ");
            for (byte b : longestSegment) {
                System.out.printf("0x%02X ", b);
            }
            System.out.println();
        } else {
            System.out.println("没有找到数据段");
        }

        StringTypeChecker.isCorrectNum(new String(longestSegment),data);
        System.out.println("ByteArrayCutter:main:"+new String(longestSegment));
    }


    /**
     * TODO 删除所有的 head
     *
     * 去掉脏数据并保留从 head 之后的所有数据
     *
     * @param data 要处理的完整数组
     * @param head 需要匹配的前缀
     * @return 切割后的数组，如果前缀不匹配，返回null
     */
    public static byte[] cutDirtyDataBeforeHead(byte[] data, byte[] head) {
        if (data == null || data.length < head.length) {
            return data; // 数据长度不足，无法匹配
        }

        // 查找 head 的起始位置
        int startIndex = -1;
        for (int i = 0; i <= data.length - head.length; i++) {
            boolean match = true;
            for (int j = 0; j < head.length; j++) {
                if (data[i + j] != head[j]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                startIndex = i;
//                break; //TODO  找到第一个 head 时退出循环
            }
        }

        if (startIndex == -1) {
            return data; // 没有找到匹配的 head，返回 null
        }

        // 从第一个 head 出现的位置开始，保留后面的数据
        byte[] result = new byte[data.length - startIndex];
        System.arraycopy(data, startIndex, result, 0, result.length);
        return result;
    }

    /**
     * 切割掉所有连续的 head 数据，包括头部和尾部
     *
     * @param data 要处理的完整数组
     * @param head 需要匹配的前缀和后缀
     * @return 切割后的数组，如果前缀和后缀不匹配，返回原数据
     */
    public static byte[] cutAllHeadsAndTails(byte[] data, byte[] head) {
        if (data == null || data.length < head.length) {
            return data; // 数据长度不足，直接返回原始数据
        }

        int offsetStart = 0;
        int offsetEnd = data.length;

        // 切割头部连续的 head
        while (offsetEnd - offsetStart >= head.length) {
            boolean match = true;
            for (int i = 0; i < head.length; i++) {
                if (data[offsetStart + i] != head[i]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                offsetStart += head.length;
            } else {
                break; // 不再匹配时退出循环
            }
        }

        // 切割尾部连续的 head
        while (offsetEnd - offsetStart >= head.length) {
            boolean match = true;
            for (int i = 0; i < head.length; i++) {
                if (data[offsetEnd - head.length + i] != head[i]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                offsetEnd -= head.length;
            } else {
                break; // 不再匹配时退出循环
            }
        }

        // 如果没有匹配到任何数据，则返回空数组
        if (offsetEnd <= offsetStart) {
            return new byte[0];
        }

        // 创建新的数组，去掉所有头部和尾部的 head 部分
        byte[] result = new byte[offsetEnd - offsetStart];
        System.arraycopy(data, offsetStart, result, 0, result.length);
        return result;
    }


    private static byte[] cutAllTails(byte[] data, byte[] head) {
        if (data == null || data.length < head.length) {
            return data; // 数据长度不足，直接返回原始数据
        }

        int offsetStart = 0;
        int offsetEnd = data.length;

        // 切割尾部连续的 head
        while (offsetEnd - offsetStart >= head.length) {
            boolean match = true;
            for (int i = 0; i < head.length; i++) {
                if (data[offsetEnd - head.length + i] != head[i]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                offsetEnd -= head.length;
            } else {
                break; // 不再匹配时退出循环
            }
        }

        // 如果没有匹配到任何数据，则返回空数组
        if (offsetEnd <= offsetStart) {
            return new byte[0];
        }

        // 创建新的数组，去掉所有头部和尾部的 head 部分
        byte[] result = new byte[offsetEnd - offsetStart];
        System.arraycopy(data, offsetStart, result, 0, result.length);
        return result;
    }


    /**
     * 去除 byte[] 中的所有回车符 (0x0D)，返回新的 byte[] 数组
     *
     * @param data 要处理的 byte[] 数组
     * @return 新的去除了 0x0D 的 byte[] 数组
     */
    public static byte[] removeCarriageReturns(byte[] data) {
        if (data == null) {
            return data;
        }
        // 使用 List<Byte> 来动态存储非 0x0D 的字节
        List<Byte> byteList = new ArrayList<>();

        // 遍历 byte[] 数组，过滤掉 0x0D
        for (byte b : data) {
            if (b != 0x0D) {
                byteList.add(b);
            }
        }

        // 将 List<Byte> 转换为 byte[] 数组
        byte[] result = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            result[i] = byteList.get(i);
        }
        return result;
    }

    /**
     * 获取最长的被 head 分割的数据段，包括第一个 head 之前的脏数据
     *
     * @param data 要处理的完整数组
     * @param head 需要匹配的头
     * @return 最长的数据段，如果没有找到则返回 null
     */
    public static byte[] getLongestDataSegment(byte[] data, byte[] head) {
        List<byte[]> segments = new ArrayList<>();
        if (data == null || data.length < head.length) {
            return null; // 数据长度不足，直接返回 null
        }

        int lastIndex = -1; // 记录上一个 head 的结束位置

        // 查找第一个 head 之前的数据段
        for (int i = 0; i <= data.length - head.length; i++) {
            boolean match = true;
            for (int j = 0; j < head.length; j++) {
                if (data[i + j] != head[j]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                // 如果第一个 head 之前有数据段，提取该段
                if (i > 0) {
                    byte[] firstSegment = new byte[i];
                    System.arraycopy(data, 0, firstSegment, 0, i);
                    segments.add(firstSegment);
                }
                lastIndex = i;
                break; // 找到第一个 head 后退出
            }
        }

        // 继续查找并提取 head 之间的数据段
        for (int i = lastIndex + head.length; i <= data.length - head.length; i++) {
            boolean match = true;
            for (int j = 0; j < head.length; j++) {
                if (data[i + j] != head[j]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                // 提取上一个 head 到当前 head 之间的数据段
                int segmentLength = i - (lastIndex + head.length);
                byte[] segment = new byte[segmentLength];
                System.arraycopy(data, lastIndex + head.length, segment, 0, segmentLength);
                segments.add(segment);
                lastIndex = i;
            }
        }

        // 处理最后一个 head 后的数据段
        if (lastIndex != -1 && lastIndex + head.length < data.length) {
            int segmentLength = data.length - (lastIndex + head.length);
            byte[] segment = new byte[segmentLength];
            System.arraycopy(data, lastIndex + head.length, segment, 0, segmentLength);
            segments.add(segment);
        }

        // 找到最长的段
        byte[] longestSegment = null;
        int maxLength = 0;
        for (byte[] segment : segments) {
            if (segment.length > maxLength) {
                maxLength = segment.length;
                longestSegment = segment;
            }
        }

        return longestSegment; // 返回最长的数据段
    }
}